package com.google.gwt.it2tool.client.widget;

import java.util.ArrayList;
import java.util.HashMap;

import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.it2tool.client.Recipe;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.FlexTable;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.PopupPanel;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.user.client.ui.Widget;

public class RecipePopupPanel extends PopupPanel{
	
	private ArrayList<IRecipeHandler> recipeHandlers = new ArrayList<IRecipeHandler>();
	
	public RecipePopupPanel(){
		super();
		setAnimationEnabled(true);
		setGlassEnabled(true);
		setAutoHideEnabled(true);
		setAutoHideOnHistoryEventsEnabled(true);
	}
	
	public void showRecipePopup(String name, int x, int y){
		showRecipePopup(null,name,x,y);
	}
	
	public void showRecipePopup(Recipe recipe, int x, int y){
		showRecipePopup(recipe,null,x,y);
	}
	
	public void addRecipeHandler(IRecipeHandler handler){
		recipeHandlers.add(handler);
	}
	
	public void removeRecipeHandler(IRecipeHandler handler){
		if (handler!=null && recipeHandlers.contains(handler)){
			recipeHandlers.remove(handler);
		}
	}
	
	private void onRecipeAdded(Recipe recipe){
		for(IRecipeHandler handler: recipeHandlers){
			handler.onRecipeAdded(recipe);
		}
	}
	
	private void onRecipeError(String error){
		for(IRecipeHandler handler: recipeHandlers){
			handler.onRecipeError(error);
		}
	}
	
	private void showRecipePopup(Recipe recipe,String name, int x, int y){
		clear();
		setPopupPosition(x, y);
		
		VerticalPanel recipePanel = new VerticalPanel();
		VerticalPanel ingridientsPanel = new VerticalPanel();
		Label title;
		
		if (recipe==null && name!=null){
			title = new Label("Rezept für: "+name);
			fillIngridientsPanelWithNoIngridients(name,ingridientsPanel);					
		}else{
			title = new Label("Rezept für: "+recipe.getName());
			fillIngridientsPanelWithIngridients(recipe,ingridientsPanel);
		}
		ingridientsPanel.addStyleName("ingridientsPanel");
		title.addStyleName("recipeLabel");
		recipePanel.add(title);
		recipePanel.add(ingridientsPanel);
		add(recipePanel);
		show();
	}
	
	private void fillIngridientsPanelWithNoIngridients(final String name,final  VerticalPanel panel){
		panel.add(new Label("Für dieses Produkt existiert noch kein Rezept"));
		HorizontalPanel buttons = new HorizontalPanel();
		final Button addRecipeButton = new Button("Rezept anlegen");
		addRecipeButton.addStyleName("addButton");
		addRecipeButton.addClickHandler(new ClickHandler() {	 			
			public void onClick(ClickEvent event) {
				panel.remove(0);
				panel.remove(0);
				panel.add(getAddIngridientsPanel(name));					
			}
		});			
		panel.add(addRecipeButton);
		panel.add(buttons);
	}
	
	private void fillIngridientsPanelWithIngridients(Recipe reci, VerticalPanel panel){
		FlexTable ingridientsTable = new FlexTable();
		ingridientsTable.addStyleName("ingridientsList");
		addIngridientsTableHeader(ingridientsTable);
		
		HashMap<String,Double> ingridients = reci.getIngridients();
		HashMap<String,String> units = reci.getUnits();
		int size = ingridients.size();
		String[] ingridientNames = new String[size];
		ingridients.keySet().toArray(ingridientNames);
		String curr;
		for(int i=0;i<size;i++){
			curr=ingridientNames[i];
			ingridientsTable.setText(i+1, 0, curr);
			ingridientsTable.setText(i+1, 1, Double.toString(ingridients.get(curr)));
			ingridientsTable.getCellFormatter().addStyleName(i+1, 1, "recipeListNumericCell");
			ingridientsTable.setText(i+1, 2, units.get(curr));
		}
		panel.add(ingridientsTable);
	}
	
	private VerticalPanel getAddIngridientsPanel(final String name){
		VerticalPanel addIngridientsPanel = new VerticalPanel();
		final FlexTable addIngridientsTable = new FlexTable();
		addIngridientsTable.addStyleName("ingridientsList");
		
		//Add Header
		addIngridientsTableHeader(addIngridientsTable);
		
		insertAddIngridientRow(addIngridientsTable);
		
		Button saveButton = new Button("speichern");
		saveButton.addClickHandler(new ClickHandler() {		
			public void onClick(ClickEvent event) {				
				saveRecipe(name, addIngridientsTable);
			}
		});		
		addIngridientsPanel.add(addIngridientsTable);
		addIngridientsPanel.add(saveButton);
		return addIngridientsPanel;
	}
	
	private void addIngridientsTableHeader(FlexTable table){
		table.setText(0, 0, "Zutat");
		table.setText(0, 1, "Menge");
		table.setText(0, 2, "Einheit");
		table.getRowFormatter().addStyleName(0, "factoryListHeader");
		table.getCellFormatter().addStyleName(0, 0, "recipeListIngridientHeader");
		table.getCellFormatter().addStyleName(0, 1, "recipeListAmountHeader");
		table.getCellFormatter().addStyleName(0, 2, "recipeListUnitHeader");
	}
	
	private void insertAddIngridientRow(final FlexTable table){
		int row= table.getRowCount();
		for(int i=0;i<3;i++){
			table.setWidget(row, i, new TextBox());
		}
		final Button plus = new Button("+");
		plus.addStyleDependentName("expandCollapse");
		plus.addClickHandler(new ClickHandler() {		
			public void onClick(ClickEvent event) {
				table.remove(plus);
				insertAddIngridientRow(table);				
			}
		});
		table.setWidget(row, 3, plus);
	}
	
	private void saveRecipe(String name, FlexTable table){
		int size = table.getRowCount();
		Recipe reci = new Recipe(name);
		
		String ingridient;
		double amount;
		String unit;
		for(int i=1;i<size;i++){
			ingridient=((TextBox)table.getWidget(i, 0)).getText();
			try{
				String amountString = ((TextBox)table.getWidget(i, 1)).getText();
				//to increase parsing accuracy when parsed by double
				if (!amountString.contains(".")){
					amountString = amountString+".0";
				}
				amount=Double.parseDouble(amountString);
			}catch (NumberFormatException e){
				onRecipeError("Menge konnte nicht gelesen werden. Kommazeichen='.'");
				hide();
				return;
			}
			unit=((TextBox)table.getWidget(i, 2)).getText();
			if(ingridient.equals("") || amount<=0 || unit.equals("") ){
				onRecipeError("Zutaten und Einheiten müssen einen Namen haben und Menge darf nicht 0 sein!");
				hide();
				return;
			}else{
				reci.addIngridient(ingridient, amount, unit);
			}
		}
		
		onRecipeAdded(reci);

		int x = getPopupLeft();
		int y = getPopupTop();
		hide();
		
		showRecipePopup(reci, x,y);
	}
	
	public interface IRecipeHandler{
		public void onRecipeAdded(Recipe recipe);
		public void onRecipeError(String error);
	}

}
